/*
 * TransiCast / Qt
 * (c) 2012 Joachim Pfeiffer
 * Please refer to http://code.google.com/p/transitacst for more information
 */
#include <QListWidget>
#include <QListWidgetItem>
#include <QXmlStreamReader>
#include <QXmlStreamAttributes>
#include <QModelIndex>

#include "bookmarks.hpp"

Bookmarks::Bookmarks(QMainWindow *parent) :
    QDialog(parent)
{
    modelParent = parent;

    bookmarksFilename = "bookmarks.xml";
    topLevelElement = "bookmarks";
    bookmarkTag = "bookmark";
    agencyNameAttr = "agencyname";
    agencyIdAttr = "agencyid";
    agencyTopAttr = "agencytop";
    agencyLeftAttr = "agencyleft";
    agencyBottomAttr = "agencybottom";
    agencyRightAttr = "agencyright";
    agencyRtAttr = "agencyrt";
    routeNameAttr = "routename";
    stopNameAttr = "stopname";
    stopIdAttr = "stopid";

    clear = false;
}

void Bookmarks::close()
{
    bookmarksWidget->deleteLater();
    mainLayout->deleteLater();
    buttonLayout->deleteLater();
    backButton->deleteLater();
    QDialog::close();
}

void Bookmarks::associateModel(TransiTreeModel *model)
{
    transiTreeModel = model;
}

void Bookmarks::open(bool clearFlag)
{
    this->setAttribute(Qt::WA_TranslucentBackground, false);

    clear = clearFlag;

    // Main layout
    mainLayout = new QVBoxLayout();
    bookmarksWidget = new QListWidget();
    mainLayout->addWidget(bookmarksWidget);

    // Back button
    buttonLayout = new QHBoxLayout();
    backButton = new QPushButton(tr("Back"));
    buttonLayout->addWidget(backButton);
    mainLayout->addLayout(buttonLayout);
    connect(backButton, SIGNAL(clicked()), this, SLOT(accept()));

    // Show dialog box
    this->setLayout(mainLayout);
    this->showMaximized();

    // Populate bookmarks list
    QListWidgetItem *line;
    QList<Bookmark *>::iterator i;
    Bookmark *bookmark;
    QString bookmarkLine;
    for (i = bookmarks.begin(); i != bookmarks.end(); ++i) {
        bookmark = *i;
        bookmarkLine = bookmark->getAgencyName();
        if (bookmark->getRouteName().length() > 0)
            bookmarkLine += ", " + bookmark->getRouteName();
        if (bookmark->getStopName().length() > 0)
            bookmarkLine += ", " + bookmark->getStopName();
        line = new QListWidgetItem(bookmarkLine);
        bookmarksWidget->addItem(line);
    }
    connect(bookmarksWidget, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT (bookmarkClicked(QListWidgetItem *)));
}

void Bookmarks::addBookmark(Bookmark *bookmark)
{
    bookmarks.append(bookmark);
    saveBookmarks();
}

void Bookmarks::accept()
{
    this->close();
    bookmarksWidget->clear();
    QDialog::accept();
    this->deleteLater();
}

void Bookmarks::loadBookmarks()
{
    while (!bookmarks.isEmpty())
        delete bookmarks.takeFirst();

    QFile *file = new QFile(bookmarksFilename);
    QXmlStreamAttributes attributes;
    QXmlStreamReader::TokenType token;

    // Return if bookmarks file not found or inaccessible
    if (!file->exists())
        return;
    if (!file->open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    // Load bookmarks file
    QXmlStreamReader xml(file);
    while (!xml.atEnd() && !xml.hasError()) {
        token = xml.readNext();
        if (token == QXmlStreamReader::StartDocument)
            continue;
        if (token == QXmlStreamReader::StartElement && xml.name() == bookmarkTag) {
            attributes = xml.attributes();
            Bookmark *bookmark = new Bookmark();
            bookmark->setAgency(attributes.value("", agencyNameAttr).toString(),
               attributes.value("", agencyIdAttr).toString(),
               attributes.value("", agencyTopAttr).toString(),
               attributes.value("", agencyLeftAttr).toString(),
               attributes.value("", agencyBottomAttr).toString(),
               attributes.value("", agencyRightAttr).toString(),
               attributes.value("", agencyRtAttr).toString());
            bookmark->setRoute(attributes.value("", routeNameAttr).toString());
            bookmark->setStop(attributes.value("", stopNameAttr).toString(), attributes.value("", stopIdAttr).toString());
            bookmarks.append(bookmark);
        }
    }
    file->close();
    file->deleteLater();
}

void Bookmarks::saveBookmarks()
{
    bookmarksFile = new QFile(bookmarksFilename);
    bookmarksFile->open(QIODevice::WriteOnly | QIODevice::Text);
    QXmlStreamWriter xml(bookmarksFile);
    Bookmark *bookmark;
    xml.setAutoFormatting(true);
    xml.writeStartDocument();
    xml.writeStartElement(topLevelElement);
    QList<Bookmark *>::iterator i;
    for (i = bookmarks.begin(); i != bookmarks.end(); ++i) {
        bookmark = *i;
        xml.writeStartElement(bookmarkTag);
        xml.writeAttribute(agencyNameAttr, bookmark->getAgencyName());
        xml.writeAttribute(agencyIdAttr, bookmark->getAgencyId());
        xml.writeAttribute(agencyTopAttr, bookmark->getAgencyTop());
        xml.writeAttribute(agencyLeftAttr, bookmark->getAgencyLeft());
        xml.writeAttribute(agencyBottomAttr, bookmark->getAgencyBottom());
        xml.writeAttribute(agencyRightAttr, bookmark->getAgencyRight());
        xml.writeAttribute(agencyRtAttr, bookmark->getAgencyRt());
        xml.writeAttribute(routeNameAttr, bookmark->getRouteName());
        xml.writeAttribute(stopNameAttr, bookmark->getStopName());
        xml.writeAttribute(stopIdAttr, bookmark->getStopId());
        xml.writeEndElement();
    }
    xml.writeEndElement();
    xml.writeEndDocument();
    bookmarksFile->flush();
    bookmarksFile->close();
    bookmarksFile->deleteLater();
}

void Bookmarks::bookmarkClicked(QListWidgetItem *item)
{
    // Find index of clicked item
    QListWidget *list = item->listWidget();
    list->setCurrentItem(item);
    int i = list->currentRow();
    selectedBookmark = bookmarks.at(i);
    bookmarksWidget->clear();
    this->close();
    this->deleteLater();
    if (clear) {
        bookmarks.removeOne(selectedBookmark);
        saveBookmarks();
    } else
        if (transiTreeModel != NULL) {
            transiTreeModel->stopLocation();
            transiTreeModel->setBookmark(selectedBookmark);
        }
}
